<?php

/**
 * Classe para gerenciar arquivos XML, podendo executar operações de leitura e escrita.
 *
 * @param String $filename - Caminho do arquivo a ser gerenciado.
 *
 * @author Bruno E. Fuhr
 * @since 21/04/2011
 */
class FXMLEditor
{
    private $filename;
    private $xml;
    private $error;

    public function __construct($filename = 'frigg.conf')
    {
        $searchPaths[] = $filename;
        $searchPaths[] = 'etc/' . $filename;
        $searchPaths[] = '../etc/' . $filename;
        $searchPaths[] = '../../etc/' . $filename;
        $searchPaths[] = '../../../etc/' . $filename;
        
        foreach ( $searchPaths as $path)
        {        
            if ( file_exists($path) )
            {
                $this->filename = $path;
                $this->xml = simplexml_load_string(file_get_contents($path));
                $this->xml = $this->XML2Array($this->xml, true);
                break;
            }
        }
    }

    /**
     * Método que obtém um valor de um nó do arquivo XML.
     * Ex.: Para pegar o valor no nó <cliente><endereco><rua>, utilizamos getValue("cliente.endereco.rua")
     * 
     * @param String $path - Caminho do nó procurado.
     * @return String - Valor do nó procurado.
     */
    public function getValue($path)
    {
        $nodes = explode('.', $path);
        $return = $this->xml;

        foreach ( $nodes as $node )
        {
            $return = $return["$node"];
        }

        return $return;
    }

    /**
     * Método para atribuir um valor a um nó do arquivo XML.
     *
     * @param string $config Caminho do nó do arquivo XML.
     * @param string $value Valor da configuração.
     */
    public function setValue($config, $value)
    {
        $xml = simplexml_load_file($this->filename);
        $configVars = str_replace('.', '->', $config);
        eval("\$xml->$configVars = '$value';");

        return $this->writeContentToFile($xml->asXML(), $this->filename);
    }

    public function getError()
    {
        return $this->error;
    }

    /**
     * Write a content to a file.
     *
     * @param string $content Content.
     * @param string $file File name.
     */
    private function writeContentToFile($content, $file)
    {
        $return = false;

        try
        {
            $handler = fopen($file, 'w');
            fwrite($handler, $content);
            fclose($handler);
            $return = true;
        }
        catch ( Exception $e )
        {
            $this->error = $e->getMessage();
        }

        return $return;
    }

    /**
     * Obtido de http://www.php.net/manual/en/function.simplexml-load-string.php
     * Transforma o objeto XML em array.
     * 
     * @param XMLObject $xml
     * @param boolean $recursive
     * @return Array 
     */
    private function XML2Array($xml, $recursive = false)
    {
        if ( !$recursive )
        {
            $array = simplexml_load_string($xml);
        }
        else
        {
            $array = $xml;
        }

        $newArray = array();
        $array = (array) $array;
        foreach ( $array as $key => $value )
        {
            $value = (array) $value;
            if ( isset($value[0]) )
            {
                $newArray [$key] = trim($value[0]);
            }
            else
            {
                $newArray [$key] = $this->XML2Array($value, true);
            }
        }
        return $newArray;
    }
}

?>
